package deployr.core;

import static deployr.core.Checksums.*;
import static java.text.MessageFormat.*;

public class AppId {

	private final String appId;

	public AppId(String appId) {
		this.appId = appId;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof AppId))
			return false;
		AppId other = (AppId) obj;
		return equalsIgnoringSeparator(other.appId) || equalsMd5(other.appId)|| equalsImplicitGroupId(other.appId);
	}

	private boolean equalsImplicitGroupId(String otherAppId) {
		return appId.equals(md5(otherAppId));
	}

	private boolean equalsMd5(String otherAppId) {
		return md5(ignoreSeparator(appId)).equals(otherAppId) || appId.equals(md5(ignoreSeparator(otherAppId)));
	}

	private boolean equalsIgnoringSeparator(String otherAppId) {
		return ignoreSeparator(appId).equals(ignoreSeparator(otherAppId));
	}

	private String ignoreSeparator(String anAppId) {
		return anAppId.replaceAll("^/", "").replaceAll("/", ":").replaceAll(":", ":").replaceAll("-", ":");
	}

	@Override
	public int hashCode() {
		return appId.hashCode();
	}

	@Override
	public String toString() {
		return appId;
	}

	public boolean match(String criteria) {
		if(ignoreSeparator(appId).equals(ignoreSeparator(criteria))) return true;
		if(md5(ignoreSeparator(appId)).equals(ignoreSeparator(criteria))) return true;
		if(ignoreSeparator(appId).equals(md5(ignoreSeparator(criteria)))) return true;

		if(implicitGroupId(appId).equals(ignoreSeparator(criteria))) return true;
		if(md5(implicitGroupId(appId)).equals(ignoreSeparator(criteria))) return true;
		if(implicitGroupId(appId).equals(md5(ignoreSeparator(criteria)))) return true;

		if(ignoreSeparator(appId).equals(implicitGroupId(criteria))) return true;
		if(md5(ignoreSeparator(appId)).equals(implicitGroupId(criteria))) return true;
		if(ignoreSeparator(appId).equals(md5(implicitGroupId(criteria)))) return true;

		return false;
	}

	private String implicitGroupId(String appId) {
		String groupId = groupId(appId);
		String artifactId = artifactId(appId);
		String version = version(appId);
		return format("{0}:{1}:{2}", groupId, artifactId, version);
	}

	public String getGroupId() {
		return groupId(appId);
	}

	private String groupId(String appId) {
		int posFirstDash = ignoreSeparator(appId).indexOf(":");
		if(posFirstDash < 0) return appId;
		return appId.substring(0, posFirstDash);
	}

	public String getArtifactId() {
		return artifactId(appId);
	}

	private String artifactId(String appId) {
		int posFirstDash = ignoreSeparator(appId).indexOf(":");
		int posLastDash = ignoreSeparator(appId).lastIndexOf(":");
		if(posFirstDash < 0) return appId;
		if(posFirstDash == posLastDash) return appId.substring(0, posLastDash);
		return appId.substring(posFirstDash + 1, posLastDash);
	}

	public String getVersion() {
		return version(appId);
	}

	private String version(String appId) {
		int posLastDash = ignoreSeparator(appId).lastIndexOf(":");
		return appId.substring(posLastDash + 1);
	}
}	